<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document https://svgwave.in </title>
</head>

<body>
</body>

</html>
<script>
    // https://blog.csdn.net/qq_40442753/article/details/111879054

    /*async特点：
        1.await只能放到async函数中
        2.相比genrator语义化更强 终极解决异步的方案 
        3.await后面可以是promise对象，也可以数字、字符串、布尔
        5.只要await语句后面promise状态变成reject，那么整个async函数会中断执行
        
    解决async函数中抛出错误影响后面代码？
        1.通过try{}catch(){}
        2.通过promise本身的catch*/

    // Promise对象的状态变化？
    //     async函数内部返回的Promise对象，必须等内部所有await命令后面的Promise对象执行完，才发生状态的改变，就是说只有async函数内部的异步操作执行完，才会执行then方法指定的回调函数 
    //     除非遇到return语句或抛出错误，
    //     只要一个await语句后面的Promise变成reject，那么整个async函数都会中断执行   
    async function f() {
        await Promise.reject('出错了');         //从这里抛出了一个reject 往后将不再执行
        await Promise.resolve('hello world');   //不会执行
    }   //Promise {<rejected>: "出错了"}


    //前一个异步操作失败?
    //     也不要中断后面的异步操作。
    //     这时可以将第一个await放在try...catch结构里面，这样不管这个异步操作是否成功，第二个await都会执行
    async function f() {
        try {
            await Promise.reject('出错了');
        } catch (e) {
        }
        return await Promise.resolve('hello world');
    }
    f()
        .then(v =>
            console.log(v)
        )  //hello world
    //另一种方法：await后面的 Promise 对象再跟一个catch方法，处理前面可能出现的错误
    async function f() {
        await Promise.reject('出错了')
            .catch(e =>
                console.log(e)
            );  //出错了
        return await Promise.resolve('hello world');
    }
    f()
        .then(v =>
            console.log(v)
        )  //hello world


    //错误处理?
    //      如果await后面的异步操作出错，那么等同于async函数返回的 Promise 对象被reject
    async function f() {
        await new Promise(function (resolve, reject) {
            throw new Error('出错了');
        });
    }
    f()
        .then(v =>
            console.log(v)
        )
        .catch(e =>
            console.log(e)
        )  //Error：出错了

    const asyncReadFile = async function () {    //async表示函数里有异步操作，
        const f1 = await readFile('/etc/fstab');     //await表示紧跟在后面的表达式需要等待结果。
        const f2 = await readFile('/etc/shells');
        console.log(f1.toString());
        console.log(f2.toString());
    };
    syncReadFile()                               //调用异步函数 


    // async返回的是一个Promise对象 可使用then方法添加回调函数 
    // 在函数执行的时候 一旦遇到await就会返回 等到异步操作完成 再接着执行函数体内后面的语句   
    // deme 
    async function getStockPriceByName(name) {     //函数前面的async关键字 表面该函数内部有异步操作 调用函数的时候 回立即返回一个Promise对象
        const symbol = await getStockSymbol(name);
        const stockPrice = await getStockPrice(symbol);
        return stockPrice;
    }
    getStockPriceByName('goog')                    //调用异步函数          
        .then(function (result) {                      //使用.then添加回调方法 
            console.log(result);
        });


    //async函数返回一个Promise对象 
    //async函数内部return语句返回的值 回成为then方法回调函数的参数  
    async function f() {
        return "hellow world";   //函数内内部return命令的返回值 会被.then方法回调函数接收到 +
    }
    f().then(v => console.log(V))  //hellow world  



    async function getData() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                var name = "syy";
                resolve(name)
            }, 1000)
        })
    }
    async function test() {
        var p = await getData();    //正常情况下 await命令后面是一个Promise对象，如果不是，会被转成一个立即resolve的Promise对象
        console.log(p)
    }
    test();     //syy


    async function f() {
        await Promise.reject('出错了'); //await命令后面的Promise对象如果变为reject状态，则reject的参数会被catch方法回调函数接收到 
    }                                //在这里await语句前面没有return 
    f()                              //当时reject方法的参数传入了catch方法的回调函数 
        .then(v =>
            console.log(v)
        )
        .catch(e =>
            console.log(e)
        )  //出错了



    //async声明方式
    async function fun() { };      //函数声明
    let fun = async function () { };//函数表达式
    let foo = async () => { };       //箭头函数    
        //...

</script>